﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TSTreeThesis.Utilities;
using ZedGraph;

namespace TSTreeThesis.DataMgr
{
    public abstract class Data
    {
        public double[] originalData;
        public double[] nomalizedData;

        //public char[] nomalizedSAXData;

        public int dataLength;

        //public double[] DWTData;
        //public int encodedDataLength;

        public double[] PAAData;
        public double[] PAANormalizedData;
        public int encodedDataLength;
        public int compressionRate;// = dataLength / encodedDataLength

        public int rRatio = 5;  // ratio to calc lower, upper
        public double[] LDTWData;
        public double[] UDTWData;
        public double[] LDTWNormalizedData;
        public double[] UDTWNormalizedData;

        public char[] LDTWSAXData;
        public char[] UDTWSAXData;
        public char[] LDTWSAXNormalizedData;
        public char[] UDTWSAXNormalizedData;

        public char[] PAASAXData;
        public char[] PAASAXNormalizedData;

        public double MEAN = 0;
        public double STD = 1;

        public int EncodedDataLength
        {
            get
            {
                return encodedDataLength;
            }
            set
            {
                if (encodedDataLength == value)
                    return;
                encodedDataLength = value;
            }
        }

        public Data(int compressionRate)
        {
            dataLength = 0;
            encodedDataLength = 0;
            this.compressionRate = compressionRate;
        }

        #region normalize
        public void normalizeData()
        {
            //Console.WriteLine("This method is not implemented yet");
            double mean = 0;
            for (int i = 0; i < dataLength; i++)
                mean += (originalData[i] / dataLength);

            double std = 0;
            for (int i = 0; i < dataLength; i++)
                std += (originalData[i] - mean) * (originalData[i] - mean);
            std = Math.Sqrt(std / (dataLength - 1));

            nomalizedData = new double[dataLength];
            //(dataLength*Utility.HIENTHI_COFF) la he so de hien thi. Thuc te thi nen bo
            //Utility.HIENTHI_COFF = dataLength / 10;
            for (int i = 0; i < dataLength; i++)
                nomalizedData[i] = (originalData[i] - mean) / std;

            MEAN = mean;
            STD = std;

        }

        #endregion

        #region PAA Tranform
        public abstract void readData(int fromIndex, int toIndex);

        public void encodeData(PAATransform transform)
        {
            PAAData = transform.Transform(compressionRate, originalData);
            encodedDataLength = PAAData.Length;
        }

        public void encodeNomalizedData(PAATransform transform)
        {
            PAANormalizedData = transform.Transform(compressionRate, nomalizedData);
            encodedDataLength = PAANormalizedData.Length;
        }

        #endregion

        #region DTW Tranform
        public void encodeDTWData(DTWTransform transform)
        {
            transform.Transform(rRatio, PAAData);
            LDTWData = transform.d_lower;
            UDTWData = transform.d_upper;
            encodedDataLength = LDTWData.Length;
        }

        public void encodeDTWNomalizedData(DTWTransform transform)
        {
            transform.Transform(rRatio, PAANormalizedData);
            LDTWNormalizedData = transform.d_lower;
            UDTWNormalizedData = transform.d_upper;
            encodedDataLength = LDTWNormalizedData.Length;
        }
        #endregion

        #region SAX Tranform
        public void encodeDTWSAXData(SAXTransform transform,int max, int min,int length)
        {
            double _max = (max - MEAN)/ STD;
            double _min = (min - MEAN) / STD;

            LDTWSAXData = transform.SaxTranform(LDTWData, _max, _min, length, encodedDataLength);
            UDTWSAXData = transform.SaxTranform(UDTWData, _max, _min, length, encodedDataLength);
            PAASAXData = transform.SaxTranform(PAAData, _max, _min, length, encodedDataLength);

            encodedDataLength = LDTWSAXData.Length;
        }

        public void encodeDTWSAXNomalizedData(SAXTransform transform, int max, int min, int length)
        {
            double _max = PAANormalizedData.Max(); //Console.WriteLine("max :" + _max.ToString()); // Math.Round((max - MEAN) / STD, 2);
            double _min = PAANormalizedData.Min(); //Console.WriteLine("min :" + _min.ToString()); // Math.Round((min - MEAN) / STD, 2);
        
            LDTWSAXNormalizedData = transform.SaxTranform(LDTWNormalizedData, _max, _min, length, encodedDataLength);
            UDTWSAXNormalizedData = transform.SaxTranform(UDTWNormalizedData, _max, _min, length, encodedDataLength);
            PAASAXNormalizedData = transform.SaxTranform(PAANormalizedData, _max, _min, length, encodedDataLength);
            encodedDataLength = LDTWSAXNormalizedData.Length;

        }
        #endregion

        #region Charts
        public void getOriginalDataChart(ref PointPairList list)
        {
            list.Clear();
            for (int i = 0; i < dataLength; i++)
            {
                double p = originalData[i];
                list.Add(i, p);
            }
        }

        public void getPAADataChart(ref PointPairList list)
        {
            list.Clear();
            for (int i = 0; i < encodedDataLength; i++)
            {
                double p = PAAData[i];
                list.Add(i, p);
            }
        }

        public void getNormalizedDataChart(ref PointPairList list)
        {
            list.Clear();
            for (int i = 0; i < dataLength; i++)
            {
                double p = nomalizedData[i];
                list.Add(i, p);
            }
        }

        public void getPAANormalizedDataChart(ref PointPairList list)
        {
            list.Clear();
            for (int i = 0; i < encodedDataLength; i++)
            {
                double p = PAANormalizedData[i];
                list.Add(i, p);
            }
        }

        public void getPAALNormalizedDataChart(ref PointPairList list)
        {
            list.Clear();
            for (int i = 0; i < encodedDataLength; i++)
            {
                double p = LDTWNormalizedData[i];
                list.Add(i, p);
            }

        }
        public void getPAAUNormalizedDataChart(ref PointPairList list)
        {
            list.Clear();
            for (int i = 0; i < encodedDataLength; i++)
            {
                double p = UDTWNormalizedData[i];
                list.Add(i, p);
            }

        }

        #endregion

    }
}
